//
//  CategoryDatabase.cpp
//  QuizMaster
//
//  Created by Jeppe Nielsen on 3/17/15.
//  Copyright (c) 2015 Jeppe Nielsen. All rights reserved.
//

#include "CategoryDatabase.hpp"
#include <iostream>
#include <sstream>
#include "StringHelper.hpp"
#include "QuestionDatabase.hpp"
#include "minijson.h"

using namespace std;

const CategoryDatabase::Categories& CategoryDatabase::GetCategories() {
    return categories;
}

void CategoryDatabase::UpdateFromJSON(std::string json) {
    const char* jsonCString = json.c_str();
    
    minijson::value root;
    
    minijson::error e = minijson::parse(jsonCString, root);
    if (e == minijson::no_error) {
        ParseJson(root);
    } else {
        std::cout<<"Error parsing json:"<<std::endl<<minijson::errstr(e)<<std::endl<<json<<std::endl;
    }
}

void CategoryDatabase::ParseJson(minijson::value& value) {
    switch (value.getType()) {
        case minijson::type::object_type: {
            minijson::object& o = value.get<minijson::object>();
            
            int id = -1;
            for (auto it = o.begin(); it!=o.end(); ++it) {
                if (it->first == "id") {
                    id = (int)atoi(it->second.get<minijson::string>().c_str());
                    break;
                }
            }
            if (id>=0) {
                Category* category = 0;
                for (auto it = o.begin(); it!=o.end(); ++it) {
                    if (it->first == "name") {
                        category = &categories[id];
                        category->id = id;
                        std::string base64Encoded =it->second.get<minijson::string>();
                        std::string text = Nano::StringHelper::base64_decode(base64Encoded);
                        category->name = text;
                    } else if (it->first == "ownerID") {
                        category = &categories[id];
                        category->id = id;
                        category->ownerID = (int)atoi(it->second.get<minijson::string>().c_str());
                    }
                }
            }
            
            break;
        }
        case minijson::type::string_type: {
            //cout<<id<<" -> "<<value.get<string>()<<endl;
            break;
        }
        case minijson::type::number_type: {
            //cout<<id<<" -> "<<value.get<minijson::number>()<<endl;
            break;
        }
        case minijson::type::boolean_type: {
            //cout<<id<<" -> "<<value.get<minijson::boolean>()<<endl;
            break;
        }
        case minijson::type::array_type: {
            minijson::array array = value.get<minijson::array>();
            for (minijson::array::iterator it = array.begin(); it!=array.end(); ++it) {
                ParseJson(*it);
            }
            break;
        }
            
        default:
            break;
    }
}

Category* CategoryDatabase::GetCategory(int index) {
    if (categories.empty()) return 0;
    int i = index % categories.size();
    int counter = 0;
    for (auto it = categories.begin(); it!=categories.end(); ++it) {
        if (counter == i) return &it->second;
        counter++;
    }
    return 0;
}

void CategoryDatabase::UpdateFromQuestions(QuestionDatabase *database) {
    const QuestionDatabase::Questions& questions = database->GetQuestions();
    
    for (Categories::iterator category = categories.begin(); category!=categories.end(); ++category) {
        for (QuestionDatabase::Questions::const_iterator question = questions.begin(); question!=questions.end(); ++question) {
            Question* questionPointer = (Question*)&question->second;
            if (question->second.categoryID == category->second.id) {
                category->second.questions.push_back(questionPointer);
                questionPointer->points = (int)category->second.questions.size() * 100;
            }
        }
    }
}




